#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <complex.h>
#include <fftw3.h>
//#include <mgl2/mgl_cf.h>

#define R0 2.20620086465074607478363406
 
typedef struct grid_str {
  int n;                
  double a,b,h;
 
  fftw_complex  *dens, *vel;
  fftw_complex  *psi, *k[7], *kzd[7], *kzv[7];     
  fftw_complex  *wrk, *wrk2;
  fftw_complex	*rhs, *rk, *rhszd, *rhszv;
  double	*r;
  
  struct grid_str *left;  // pointer to grid on the left
  struct grid_str *right; // pointer to grid on the right

} type_grid, *grid_ptr;



typedef struct input_str {
  char	   res_name[80];   //  restart file name
  char     runname[80];    //  name of run
  int      n_grids;        //  number of starting grids   
  int      n_points[128];  //  number of gridpoints on starting grids
  double   h;              //  step on smallest grid
  double   cfl;            //  cfl constant
  double   mr_tol;	   //  mesh refinement tolerance
  double   t_max;          //  terminal time
  double   tau, m_p, p_rr; //  self-similar properties
  double   L, beta, v;
  int      ic_type;        //  type of initial condition
  int	   zakh;	   //  zakharov switch
  
  double   a;              //  amplitude of IC
  double   sigma;          //  width of gaussian type ICs
  
  int	   dims;	   //  dimensions 2D, 3D
  double  hyp_v;	   //  hyper viscosity coefficient	
  double  tau_skip;	   //  frequency of ss entries
  int  out_skip;        //  frequency of profile writes
  grid_ptr right;	   //  pointer to rightmost grid
  grid_ptr left;	   //  pointer to leftmost grid

} input, *input_ptr;

extern void read_input_parameters(input_ptr params);
extern void draw_tf(char *fname);
extern void write_tf(char* fname);
extern void setup_ic(input_ptr p);
extern void init_f(input_ptr p);
extern void derivative_1();
extern void derivative_2();
extern void derivative_4();
extern void rhs();
extern void evolve_erk4(input_ptr p);
extern void evolve_erk6(input_ptr p);
extern void update_boundaries();
extern void add_grid(input_ptr p);
extern void find_ss(input_ptr p);
extern void find_beta(input_ptr p);
extern double regrid(input_ptr p);
